package com.spring.service;

import com.google.common.collect.Lists;
import com.nebula.core.client.NebulaTemplate;
import com.nebula.core.constant.Constant;
import com.nebula.core.dsl.operation.FunctionOperation;
import com.vesoft.nebula.client.graph.data.ResultSet;
import org.neo4j.cypherdsl.core.Cypher;
import org.neo4j.cypherdsl.core.Node;
import org.neo4j.cypherdsl.core.Relationship;
import org.neo4j.cypherdsl.core.Statement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author zhangtao
 * @create 2023/9/8 10:47
 */
@Service
public class NebulaService {

    @Autowired
    private NebulaTemplate nebulaTemplate;

    public ResultSet findPlayerRelation(String vid, String edgeType) {
        return nebulaTemplate.go()
                .from(vid)
                .over(false, true, edgeType)
                .yield(FunctionOperation.properties(Constant.EDGE_START), "start")
                .yield(FunctionOperation.properties(Constant.EDGE_END), "end")
                .yield(Constant.EDGE, "e")
                .excute();
    }

    public ResultSet getPlayerProp(String vid) {
        return nebulaTemplate.fetch()
                .on("player")
                .from(vid)
                .yield("player.name", "name")
                .yield("player.age", "age")
                .excute();
    }

    public ResultSet getSubgraph(Object vid, int steps) {
        return nebulaTemplate.getSubgraph()
                .steps(steps)
                .from(vid)
                .yield("nodes", "relationships")
                .excute();
    }

    public ResultSet findPath(Object src, Object dst) {
        return nebulaTemplate.findPath()
                .all()
                .fromTo(Lists.newArrayList(src), Lists.newArrayList(dst))
                .yield("p")
                .excute();
    }

    public ResultSet findDirectRelation(String id) {
        Node player = Cypher.node("player").named("e");
        Node t = Cypher.anyNode("t");
        Relationship r = player.relationshipBetween(t).named("r");
        Statement statement = Cypher.match(r)
                .where(player.internalId().eq(Cypher.literalOf(id)))
                .returning(player, t, r).build();

        return nebulaTemplate.query(statement);
    }
}

